home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_30 / data.c next >
C/C++ Source or Header  |  1995-01-01  |  5KB  |  238 lines

  1. #include "midi.h"
  2. /* 
  3. Copright 1988, G.E.S. Consulting
  4.  
  5. NORMAL MODE tutorial, RECORD and PLAY
  6.     for those who like to do all the work themselves!
  7.  
  8.  
  9. NOTE:
  10. struct eventlist {
  11.     struct event *f; ptr to first event on que
  12.     struct event *c; ptr to current event on que
  13.     struct event *l; ptr to last event on que
  14.     }
  15. Library does NOT maintain  (or have knowledge of) this structure.
  16. You are free to devise you own way to manage event lists if you wish.
  17. */
  18. main()
  19.     {
  20.     struct event *p,*op, *qp = (struct event *)0;
  21.     unsigned char r,sr;/* running status storage for get_event and show_event */
  22.     int count= 0, eventno = 0; /* counters for show_event */
  23.     
  24.     init_event_list(10); /* allocate 10000 events */
  25.     mpu_init(); /* install driver */
  26.     
  27.     /* tell em how to stop */
  28.     
  29.     printf("Playback will begin when you hit middle C\n");
  30.     
  31.     /* initialize running status */
  32.     r = 0;
  33.     sr = 0;
  34.     
  35.     /* note MIDI_START is necessary to get mpu to actually do something
  36.     the first time around. see tech manual p. 20 */
  37.     
  38.     mpu_control(START_RECORD|MIDI_START);
  39.     
  40.     /* while MPU is still talking */
  41.     
  42.     while(p = get_event(&r,10))
  43.         {
  44.         show_event(++eventno,&count,&sr,p); /* show em what they did */
  45.         
  46.         if (!qp) /* chain events together */
  47.             {
  48.             qp = p;
  49.             op = p;
  50.             }
  51.         else
  52.             {
  53.             op->n = p;
  54.             op = p;
  55.             }
  56.         
  57.         /* test for middle c pressed */
  58.         
  59.         if (p->d.data[0] == 60  /* middle c */
  60.             && ((p->status == 0 && r == 0x90) || p->status == 0x90)) 
  61.             break; /* ON or OFF */ /* all done */
  62.         }
  63.     
  64.     /* tell MPU to finish up */
  65.     
  66.     mpu_control(STOP_RECORD|MIDI_STOP);
  67.     
  68.     /* wait for END of DATA */
  69.     
  70.     while(p = get_event(&r,10))
  71.         {
  72.         show_event(++eventno,&count,&sr,p);
  73.         op->n = p;
  74.         op = p;
  75.         if (p->tbyte < 240 && p->status == 0xfc) /* end of data */
  76.             break;
  77.         }
  78.  
  79.     /* reset running status */
  80.     
  81.     r = 0;
  82.     /* tell MPU which tracks to play */
  83.     
  84.     active_tracks(TRACK_1);
  85.     clear_play_counters();
  86.     
  87.     /* start playing */
  88.     
  89.     mpu_control(START_PLAY|MIDI_START);
  90.     op = qp;
  91.     
  92.     /* satisy requests for data */
  93.     
  94.     while(p = get_event(&r,10))
  95.         {
  96.         show_event(++eventno,&count,&sr,p);
  97.         if (p->tbyte == 255 && p->status >= 0xf0 && p->status <= 0xf7)
  98.             {
  99.             send_message(op);
  100.             op = op->n;
  101.             }
  102.         
  103.         /* check for end of track */
  104.         
  105.         if (p->tbyte == 255 && p->status == 0xfc) /* end of data */
  106.             break;
  107.         }
  108.     mpu_control(STOP_PLAY|MIDI_STOP);
  109.     reset_mpu();
  110.     mpu_close();
  111.     }
  112.  
  113. /* a handy routine to make an event human readable */
  114.  
  115. char *etab[] = {
  116.     "Note Off ",
  117.     "Note On  ",
  118.     "Key Pres ",
  119.     "Cntrl Chg",
  120.     "Program  ",
  121.     "Chan Pres",
  122.     "Ptch Weel",
  123.     "MIDI MARK"
  124.     };
  125.  
  126. /* Midi Message Length table */
  127.  
  128. int ltab[] = {2,2,2,2,1,1,2,0};
  129. show_event(int eventno,int *rcount,unsigned char *running,struct event *p)
  130.     {
  131.     printf("Event %03d ", eventno);
  132.     if (p->tbyte < 0xf0) /* MIDI MESSAGE OR MPU MARK */
  133.         {
  134.         int etype;
  135.         int chan;
  136.         if (!p->status)
  137.             p->status = *running;
  138.         else if (p->status < 0xf0)
  139.             *running = p->status;
  140.         etype = (p->status >> 4) & 7;
  141.         if (etype == 1 && p->d.data[1] == 0)
  142.             etype--;
  143.         chan  = (p->status & 7);
  144.         *rcount += p->tbyte;
  145.         printf("Timng (%02x) %3d ",p->tbyte,*rcount);
  146.         printf("%s ",etab[etype]);
  147.         switch(etype)
  148.             {
  149.         case 0:
  150.             printf("Pitch (%03d) ",p->d.data[0]);
  151.             break;
  152.         case 1:
  153.             printf("Pitch (%03d) Velocity (%03d) ",p->d.data[0],
  154.                 p->d.data[1]);
  155.             break;
  156.         case 2:
  157.             printf("Pitch (%03d) Pressure (%03d) ",p->d.data[0],
  158.                 p->d.data[1]);
  159.             break;
  160.         case 3:
  161.             printf("Number (%03d) Value (%03d) ",p->d.data[0],
  162.                 p->d.data[1]);
  163.             break;
  164.         case 4:
  165.             printf("Number (%03d) ",p->d.data[0]);
  166.             break;
  167.         case 5:
  168.             printf("Pressure (%03d) ",p->d.data[0]);
  169.             break;
  170.         case 6:
  171.             printf("LSB (%03d) MSB (%03d) ",p->d.data[0],
  172.                 p->d.data[1]);
  173.             break;
  174.         case 7:
  175.             switch(p->status)
  176.                 {
  177.             case 0xf8:
  178.                 printf("NOP ");
  179.                 break;
  180.             case 0xf9:
  181.                 *rcount = 0;
  182.                 printf("Measure End ");
  183.                 break;
  184.             case 0xfc:
  185.                 printf("Data End ");
  186.                 break;
  187.             default:
  188.                 printf("INVALID! ");
  189.                 }
  190.             break;
  191.             }
  192.         }
  193.     else /* MPU MESSAGE */
  194.         {
  195.         int chan = p->status & 7;
  196.         int stat = p->status;
  197.         printf("Timng (%02x) %3d ",0,*rcount);
  198.         printf("MPU MESSAGE ");
  199.         if (stat >= 0xf0 && stat <= 0xf7)
  200.             printf("Data Request: Channel %1d :",chan);
  201.         else switch(stat)
  202.             {
  203.         case 0xf8:
  204.             *rcount += 240;
  205.             printf("Timer Overflow");
  206.             break;
  207.         case 0xf9:
  208.             printf("Conductor Data Request");
  209.             break;
  210.         case 0xfa:
  211.             printf("Midi Start");
  212.             break;
  213.         case 0xfb:
  214.             printf("Midi Continue");
  215.             break;
  216.         case 0xfc:
  217.             printf("Midi Stop");
  218.             break;
  219.         case 0xfd:
  220.             printf("CLOCK to HOST");
  221.             break;
  222.         case 0xfe:
  223.             printf("ACK");
  224.             break;
  225.         case 0xff:
  226.             {
  227.             int i;
  228.             printf("SYS EX DATA[");
  229.             for (i = 0; i < p->dlen; i++)
  230.                 printf("%02x",p->dlen > 4 ? p->d.dptr[i] : p->d.data[i]);
  231.         printf("]");
  232.         }
  233.         break;
  234.         }
  235.     }
  236. printf("\n");
  237. }
  238.